/**
    Copyright (c) 2010 yakiimo02
    Distributed under the New BSD License.
    See included license.txt or http://www.yakiimo3d.com/NewBSDLicense.txt
**/

#pragma once

#include "StructuredBufferTypes.h"

#include <vector>

/**    
    @brief  Constant buffer struct for compute shader.
    @author yakiimo02
    @date    2010/01/30
*/
#pragma pack(push,1)
struct ConstantBuf
{
public:
    // bounds of the complex number plane
    float    fMinRe;
    float    fMaxRe;
    float    fMinIm;
    float    fMaxIm;
    
    float    fMinReZoom;
    float    fMaxReZoom;
    float    fMinImZoom;
    float    fMaxImZoom;

    float    fReC;                // precalculated const
    float    fImC;                // precalculated const

    // input dim
    int        nInputWidth;
    int        nInputHeight;
    // output dim
    int        nOutputWidth;
    int        nOutputHeight;

    // maximum iterations to decide whether an complex number is in the mandelbrot set.
    int        nMaxIteration;        // largest iteration among the 3 rgb maxIterations
    int        maxIterations[ 3 ];    // max iterations for 3 rgbs.

    float  padding[ 2 ];        // constant buffer ByteWidth has to be a multiple of 16

public:
    ConstantBuf()
    {
#if 0
        // buddhabrot
        maxIterations[ 0 ] = 1024;
        maxIterations[ 1 ] = 1024;
        maxIterations[ 2 ] = 1024;
#else
        // nebulabrot
        maxIterations[ 0 ] = 10000;
        maxIterations[ 1 ] = 1000;
        maxIterations[ 2 ] = 100;
#endif
    }
};
#pragma pack(pop)

// assert( BUDDHABROT_SAMPLES_PER_FRAME = BUDDHABROT_CS_WIDTH * BUDDHABROT_CS_HEIGHT )
#define BUDDHABROT_SAMPLES_PER_FRAME        10000

// Use 100*100=10,000 compute shader threads
#define BUDDHABROT_CS_WIDTH            100
#define BUDDHABROT_CS_HEIGHT        100

/**    
    @brief  Buddhabrot base class.
    @author yakiimo02
    @date    2010/01/30
*/
class BuddhabrotBase
{
public:
    BuddhabrotBase();
    ~BuddhabrotBase();

    void TranslateCenter( const D3DXVECTOR2& vDeltaCenter );
    void ZoomScale( const float fDeltaScale );

    inline void SetnMaxIterations( const int nRGB, const int nMaxIterations ) { m_cb.maxIterations[ nRGB ] = nMaxIterations; }

    inline const ConstantBuf*    GetpConstantBuf() const { return &m_cb; }
    inline D3DXVECTOR2            GetvCenter() const { return m_vCenter; }
    inline float                GetfZoomScale() const { return m_fZoomScale; }
    inline int                    GetnMaxIterations( const int nRGB ) const { return m_cb.maxIterations[ nRGB ]; }

protected:
    void CreateColorTable();
    void UpdateConstantBuf( int nInputWidth, int nInputHeight, int nOutputWidth, int nOutputHeight );

protected:
    D3DXVECTOR2                    m_vCenter;
    float                        m_fZoomScale;
    ConstantBuf                    m_cb;
};
